package service

import (
	"context"
	"net/http"

	"github.com/mars/internal/admin/core/domain"
	"github.com/mars/pkg/errors"
	"github.com/mars/pkg/loggers"
)

type CartSrv interface {
	GetCartList(ctx context.Context, params domain.CartQueryParams) ([]domain.CartItem, int64, error)
	GetCartItem(ctx context.Context, cartID string) (*domain.CartItem, error)
	GetUserCartItems(ctx context.Context, openid string) ([]domain.CartItem, error)
	GetCartItemsByProduct(ctx context.Context, productID string) ([]domain.CartItem, error)
	GetCartItemsByStatus(ctx context.Context, status domain.CartStatus) ([]domain.CartItem, error)
	GetCartStats(ctx context.Context) (*domain.CartStats, error)
	SearchCartItems(ctx context.Context, keyword string) ([]domain.CartItem, error)
}

type cartService struct {
	cartDomain domain.CartGateway
}

var _ CartSrv = (*cartService)(nil)

func newCartService(fc domain.Factory) *cartService {
	return &cartService{
		cartDomain: fc.CartDomain(),
	}
}

// GetCartList 获取购物车列表
func (c *cartService) GetCartList(ctx context.Context, params domain.CartQueryParams) ([]domain.CartItem, int64, error) {
	cartItems, total, err := c.cartDomain.GetCartList(ctx, params)
	if err != nil {
		loggers.Error(ctx, "get cart list failed", err)
		return nil, 0, errors.NewWithStackWithoutCode(http.StatusInternalServerError, "get cart list failed")
	}
	return cartItems, total, nil
}

// GetCartItem 根据ID获取购物车项详情
func (c *cartService) GetCartItem(ctx context.Context, cartID string) (*domain.CartItem, error) {
	cartItem, err := c.cartDomain.GetCartItem(ctx, cartID)
	if err != nil {
		loggers.Error(ctx, "get cart item failed", err)
		return nil, errors.NewWithStackWithoutCode(http.StatusInternalServerError, "get cart item failed")
	}
	return cartItem, nil
}

// GetUserCartItems 获取用户的购物车列表
func (c *cartService) GetUserCartItems(ctx context.Context, openid string) ([]domain.CartItem, error) {
	cartItems, err := c.cartDomain.GetUserCartItems(ctx, openid)
	if err != nil {
		loggers.Error(ctx, "get user cart items failed", err)
		return nil, errors.NewWithStackWithoutCode(http.StatusInternalServerError, "get user cart items failed")
	}
	return cartItems, nil
}

// GetCartItemsByProduct 根据产品ID获取购物车项列表
func (c *cartService) GetCartItemsByProduct(ctx context.Context, productID string) ([]domain.CartItem, error) {
	cartItems, err := c.cartDomain.GetCartItemsByProduct(ctx, productID)
	if err != nil {
		loggers.Error(ctx, "get cart items by product failed", err)
		return nil, errors.NewWithStackWithoutCode(http.StatusInternalServerError, "get cart items by product failed")
	}
	return cartItems, nil
}

// GetCartItemsByStatus 根据状态获取购物车项列表
func (c *cartService) GetCartItemsByStatus(ctx context.Context, status domain.CartStatus) ([]domain.CartItem, error) {
	cartItems, err := c.cartDomain.GetCartItemsByStatus(ctx, status)
	if err != nil {
		loggers.Error(ctx, "get cart items by status failed", err)
		return nil, errors.NewWithStackWithoutCode(http.StatusInternalServerError, "get cart items by status failed")
	}
	return cartItems, nil
}

// GetCartStats 获取购物车统计信息
func (c *cartService) GetCartStats(ctx context.Context) (*domain.CartStats, error) {
	stats, err := c.cartDomain.GetCartStats(ctx)
	if err != nil {
		loggers.Error(ctx, "get cart stats failed", err)
		return nil, errors.NewWithStackWithoutCode(http.StatusInternalServerError, "get cart stats failed")
	}
	return stats, nil
}

// SearchCartItems 搜索购物车项
func (c *cartService) SearchCartItems(ctx context.Context, keyword string) ([]domain.CartItem, error) {
	cartItems, err := c.cartDomain.SearchCartItems(ctx, keyword)
	if err != nil {
		loggers.Error(ctx, "search cart items failed", err)
		return nil, errors.NewWithStackWithoutCode(http.StatusInternalServerError, "search cart items failed")
	}
	return cartItems, nil
}
